package com.faithnmn.utils;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.text.TextUtils;
import android.util.Log;
import android.widget.RemoteViews;


@SuppressLint("NewApi")
public class NotificationsHelper{
    private String background_url;
    private final static int NORMAL = 0x00;
    private final static int NORMAL_BITMAP = 0x01;
    private final static int NORMAL_URL = 0x02;
    private final static int BIG_TEXT_STYLE = 0x03;
    private final int BIG_PICTURE_STYLE = 0x04;
    private final static int INBOX_STYLE = 0x05;
    private final static int CUSTOM_VIEW = 0x06;
    private Bitmap largeIconBitmap;
    private String normalUrl;
    private int smallIcon;
    private int NOTIFICATION_ID;
    private Class<?> resultActivity;
    private String title;
    private String content;
    private static NotificationManager mNotificationManager;
    private Context context;
    private boolean autoCancel = false;
    private boolean isOnGoing = false;
    private String bigContentTitleInbox,sumaryTextInbox;
    public NotificationsHelper(Context context,Class<?> resultActivity,int smallIcon,int largeIcon,int NOTIFICATION_ID){
    	this.context = context;
    	this.resultActivity = resultActivity;
    	this.smallIcon = smallIcon;
    	mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    	largeIconBitmap = BitmapFactory.decodeResource(context.getResources(), largeIcon);
    	this.NOTIFICATION_ID = NOTIFICATION_ID;
    }
    
    public NotificationsHelper setTitle(String title){
    	this.title = title;
    	return this;
    }
    
    public NotificationsHelper setContent(String content){
    	this.content = content;
    	return this;
    }
    
    public NotificationsHelper setAutoCancel(boolean autoCancel){
    	this.autoCancel = autoCancel;
    	return this;
    }
    
    public NotificationsHelper setOnGoing(boolean isOnGoing){
    	this.isOnGoing = isOnGoing;
    	return this;
    }
    
    public NotificationsHelper setLargeIconBitmap(Bitmap largeIconBitmap){
    	this.largeIconBitmap = largeIconBitmap;
    	return this;
    }
    
    public NotificationsHelper setLargeIconUrl(String url){
    	this.normalUrl = url;
    	return this;
    }
    
    public NotificationsHelper setBigContentTitleInbox(String bigContentTitleInbox){
    	this.bigContentTitleInbox = bigContentTitleInbox;
    	return this;
    }
    
    public NotificationsHelper setSumaryTitleInbox(String sumaryTitleInbox){
    	this.sumaryTextInbox = sumaryTitleInbox;
    	return this;
    }
    
    public NotificationsHelper setBackgroundUrl(String url){
    	this.background_url = url;
    	return this;
    }
    
    public void showNormalStyle() {
        new CreateNotification(NORMAL).execute();
    }
    
    public void showNormalStyleURL() {
        new CreateNotification(NORMAL_URL).execute();
    }
    
    public void showNormalStyleBitmap() {
        new CreateNotification(NORMAL_BITMAP).execute();
    }

    public void showBigTextStyle() {
        new CreateNotification(BIG_TEXT_STYLE).execute();
    }

    public void showBigPictureStyle() {
        new CreateNotification(BIG_PICTURE_STYLE).execute();
    }

    public void showInboxStyle(ArrayList<String> linesInbox) {
        new CreateNotification(INBOX_STYLE,linesInbox).execute();
    }

    public void showCustomView() {
        new CreateNotification(CUSTOM_VIEW).execute();
    }

    public void setSmallIcon(int smallIcon){
    	this.smallIcon = smallIcon;
    }
    
    /**
     * Notification AsyncTask to create and return the
     * requested notification.
     *
     * @see CreateNotification#CreateNotification(int)
     */
    public class CreateNotification extends AsyncTask<Void, Void, Void> {
        private int style = NORMAL;
        private int customLayoutId,customTextViewId;
        private String customTextViewValue;
        private ArrayList<String> inboxLines;
        /**
         * Main constructor for AsyncTask that accepts the parameters below.
         *
         * @param style {@link #NORMAL}, {@link #BIG_TEXT_STYLE}, {@link #BIG_PICTURE_STYLE}, {@link #INBOX_STYLE}
         * @see #doInBackground
         */
        public CreateNotification(int style) {
            this.style = style;
        }
        public CreateNotification(int style,int customLayoutId,int customTextViewId,String customTextViewValue) {
            this.style = style;
            this.customLayoutId = customLayoutId;
            this.customTextViewId = customTextViewId;
            this.customTextViewValue = customTextViewValue;
        }
        public CreateNotification(int style,ArrayList<String> inboxLines) {
            this.style = style;
            this.inboxLines = inboxLines;
        }

        /**
         * Creates the notification object.
         *
         * @see #setNormalNotification
         * @see #setBigTextStyleNotification
         * @see #setBigPictureStyleNotification
         * @see #setInboxStyleNotification
         */
        @Override
        protected Void doInBackground(Void... params) {
            Notification noti = new Notification();
            switch (style)
            {
                case NORMAL:
                    noti = setNormalNotification();
                    break;
                case NORMAL_BITMAP:
                    noti = setNormalNotificationCustomLargeIconBitmap();
                    break;
                case NORMAL_URL:
                    noti = setNormalNotificationCustomLargeIcon();
                    break;
                case BIG_TEXT_STYLE:
                    noti = setBigTextStyleNotification();
                    break;
                case BIG_PICTURE_STYLE:
                    noti = setBigPictureStyleNotification();
                    break;
                case INBOX_STYLE:
                    noti = setInboxStyleNotification(inboxLines);
                    break;
                case CUSTOM_VIEW:
                    noti = setCustomViewNotification(customLayoutId,customTextViewId,customTextViewValue);
                    break;
            }
            noti.defaults |= Notification.DEFAULT_LIGHTS;
            noti.defaults |= Notification.DEFAULT_VIBRATE;
            noti.defaults |= Notification.DEFAULT_SOUND;
            noti.when = System.currentTimeMillis();
            noti.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN){
            	noti.priority = Notification.PRIORITY_MAX;
            }
            mNotificationManager.notify(NOTIFICATION_ID, noti);
            return null;
        }
    }

    private Notification setNormalNotification() {
        PendingIntent resultPendingIntent = null;
        // Setup an explicit intent for an ResultActivity to receive.
        Intent resultIntent = new Intent(context, resultActivity);
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN){
        	// TaskStackBuilder ensures that the back button follows the recommended convention for the back key.
            TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
            // Adds the back stack for the Intent (but not the Intent itself).
            stackBuilder.addParentStack(resultActivity);
            // Adds the Intent that starts the Activity to the top of the stack.
            stackBuilder.addNextIntent(resultIntent);
            resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        }else{
        	resultPendingIntent = PendingIntent.getActivity(context, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        }

        return new NotificationCompat.Builder(context)
                .setSmallIcon(smallIcon)
                .setAutoCancel(true)
                .setLargeIcon(largeIconBitmap)
                .setContentIntent(resultPendingIntent)
                .setContentTitle(title)
                .setContentText(content).build();
    }

    private Notification setNormalNotificationCustomLargeIcon() {
        Bitmap remote_picture = null;
        PendingIntent resultPendingIntent = null;
        try {
        	if(normalUrl != null){
        		remote_picture = BitmapFactory.decodeStream((InputStream) new URL(normalUrl).getContent());
        	}else{
        		Log.e("inboxStyleNotification","Empty Large Icon Url!");
        	}
        } catch (IOException e) {
            e.printStackTrace();
        }
        // Setup an explicit intent for an ResultActivity to receive.
        Intent resultIntent = new Intent(context, resultActivity);
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN){
        	// TaskStackBuilder ensures that the back button follows the recommended convention for the back key.
            TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
            // Adds the back stack for the Intent (but not the Intent itself).
            stackBuilder.addParentStack(resultActivity);
            // Adds the Intent that starts the Activity to the top of the stack.
            stackBuilder.addNextIntent(resultIntent);
            resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        }else{
        	resultPendingIntent = PendingIntent.getActivity(context, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        }

        return new NotificationCompat.Builder(context)
                .setSmallIcon(smallIcon)
                .setAutoCancel(autoCancel)
                .setOngoing(isOnGoing)
                .setLargeIcon(remote_picture)
                .setContentIntent(resultPendingIntent)
                .setContentTitle(title)
                .setContentText(content).build();
    }
    
    private Notification setNormalNotificationCustomLargeIconBitmap() {
        PendingIntent resultPendingIntent = null;
        // Setup an explicit intent for an ResultActivity to receive.
        Intent resultIntent = new Intent(context, resultActivity);
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN){
        	// TaskStackBuilder ensures that the back button follows the recommended convention for the back key.
            TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
            // Adds the back stack for the Intent (but not the Intent itself).
            stackBuilder.addParentStack(resultActivity);
            // Adds the Intent that starts the Activity to the top of the stack.
            stackBuilder.addNextIntent(resultIntent);
            resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        }else{
        	resultPendingIntent = PendingIntent.getActivity(context, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        }

        return new NotificationCompat.Builder(context)
                .setSmallIcon(smallIcon)
                .setAutoCancel(autoCancel)
                .setOngoing(isOnGoing)
                .setLargeIcon(largeIconBitmap)
                .setContentIntent(resultPendingIntent)
                .setContentTitle(title)
                .setContentText(content).build();
    }
    
    /**
     * Big Text Style Notification
     *
     * @return Notification
     * @see CreateNotification
     */
    private Notification setBigTextStyleNotification() {
        Bitmap remote_picture = null;
        // Create the style object with BigTextStyle subclass.
        NotificationCompat.BigTextStyle notiStyle = new NotificationCompat.BigTextStyle();
        notiStyle.setBigContentTitle("Big Text Expanded");
        notiStyle.setSummaryText("Nice big text.");
        try {
        	if(!TextUtils.isEmpty(background_url)){
        		remote_picture = BitmapFactory.decodeStream((InputStream) new URL(background_url).getContent());
        	}else{
        		Log.e("inboxStyleNotification","Empty Large Icon Url!");
        	}
        } catch (IOException e) {
            e.printStackTrace();
        }
        // Add the big text to the style.
        CharSequence bigText = "This is an example of a large string to demo how much " +
                               "text you can show in a 'Big Text Style' notification.";
        notiStyle.bigText(bigText);
        // Creates an explicit intent for an ResultActivity to receive.
        Intent resultIntent = new Intent(context, resultActivity);
        PendingIntent resultPendingIntent;
		if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN){
        	// TaskStackBuilder ensures that the back button follows the recommended convention for the back key.
            TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
            // Adds the back stack for the Intent (but not the Intent itself).
            stackBuilder.addParentStack(resultActivity);
            // Adds the Intent that starts the Activity to the top of the stack.
            stackBuilder.addNextIntent(resultIntent);
            resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        }else{
        	resultPendingIntent = PendingIntent.getActivity(context, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        }
        return new NotificationCompat.Builder(context)
                .setSmallIcon(smallIcon)
                .setAutoCancel(autoCancel)
                .setOngoing(isOnGoing)
                .setLargeIcon(remote_picture)
                .setContentIntent(resultPendingIntent)
                .setContentTitle(title)
                .setContentText(content)
                .setStyle(notiStyle).build();
    }

    /**
     * Big Picture Style Notification
     *
     * @return Notification
     * @see CreateNotification
     */
    private Notification setBigPictureStyleNotification() {
        Bitmap remote_picture = null;
        // Create the style object with BigPictureStyle subclass.
        NotificationCompat.BigPictureStyle notiStyle = new NotificationCompat.BigPictureStyle();
        notiStyle.setBigContentTitle("Big Picture Expanded");
        notiStyle.setSummaryText("Nice big picture.");
        try {
        	if(!TextUtils.isEmpty(background_url)){
        		remote_picture = BitmapFactory.decodeStream((InputStream) new URL(background_url).getContent());
        	}else{
        		Log.e("inboxStyleNotification","Empty Large Icon Url!");
        	}
        } catch (IOException e) {
            e.printStackTrace();
        }
        // Add the big picture to the style.
        notiStyle.bigPicture(remote_picture);
        // Creates an explicit intent for an ResultActivity to receive.
        Intent resultIntent = new Intent(context, resultActivity);
        PendingIntent resultPendingIntent;
		if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN){
        	// TaskStackBuilder ensures that the back button follows the recommended convention for the back key.
            TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
            // Adds the back stack for the Intent (but not the Intent itself).
            stackBuilder.addParentStack(resultActivity);
            // Adds the Intent that starts the Activity to the top of the stack.
            stackBuilder.addNextIntent(resultIntent);
            resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        }else{
        	resultPendingIntent = PendingIntent.getActivity(context, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        }
        return new NotificationCompat.Builder(context)
                .setSmallIcon(smallIcon)
                .setAutoCancel(autoCancel)
                .setOngoing(isOnGoing)
                .setLargeIcon(remote_picture)
                .setContentIntent(resultPendingIntent)
                .setContentTitle(title)
                .setContentText(content)
                .setStyle(notiStyle).build();
    }

    /**
     * Inbox Style Notification
     *
     * @return Notification
     * @see CreateNotification
     */
    private Notification setInboxStyleNotification(ArrayList<String> lines) {
        Bitmap remote_picture = null;
        // Create the style object with InboxStyle subclass.
        NotificationCompat.InboxStyle notiStyle = new NotificationCompat.InboxStyle();
        notiStyle.setBigContentTitle(bigContentTitleInbox);
        // Add the multiple lines to the style.
        // This is strictly for providing an example of multiple lines.
        int index = lines.size() >= 5?5:lines.size();
        for (int i=0; i < index; i++) {
            notiStyle.addLine(lines.get(i));
        }
        notiStyle.setSummaryText(sumaryTextInbox);
        try {
        	if(!TextUtils.isEmpty(background_url)){
        		remote_picture = BitmapFactory.decodeStream((InputStream) new URL(background_url).getContent());
        	}else{
        		Log.e("inboxStyleNotification","Empty Large Icon Url!");
        	}
        } catch (IOException e) {
            e.printStackTrace();
        }
        // Creates an explicit intent for an ResultActivity to receive.
        Intent resultIntent = new Intent(context, resultActivity);
        PendingIntent resultPendingIntent;
		if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN){
        	// TaskStackBuilder ensures that the back button follows the recommended convention for the back key.
            TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
            // Adds the back stack for the Intent (but not the Intent itself).
            stackBuilder.addParentStack(resultActivity);
            // Adds the Intent that starts the Activity to the top of the stack.
            stackBuilder.addNextIntent(resultIntent);
            resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        }else{
        	resultPendingIntent = PendingIntent.getActivity(context, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        }
        return new NotificationCompat.Builder(context)
                .setSmallIcon(smallIcon)
                .setAutoCancel(autoCancel)
                .setOngoing(isOnGoing)
                .setLargeIcon(remote_picture)
                .setContentIntent(resultPendingIntent)
                .setContentTitle(title)
                .setContentText(content)
                .setStyle(notiStyle).build();
    }

    /**
     * Custom View Notification
     *
     * @return Notification
     * @see CreateNotification
     */
    private Notification setCustomViewNotification(int layoutId,int textViewId,String textViewValue) {

        // Creates an explicit intent for an ResultActivity to receive.
        Intent resultIntent = new Intent(context, resultActivity);
        PendingIntent resultPendingIntent;
		if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN){
        	// TaskStackBuilder ensures that the back button follows the recommended convention for the back key.
            TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
            // Adds the back stack for the Intent (but not the Intent itself).
            stackBuilder.addParentStack(resultActivity);
            // Adds the Intent that starts the Activity to the top of the stack.
            stackBuilder.addNextIntent(resultIntent);
            resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        }else{
        	resultPendingIntent = PendingIntent.getActivity(context, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        }
        // Create remote view and set bigContentView.
        RemoteViews expandedView = new RemoteViews(context.getPackageName(), layoutId);
        expandedView.setTextViewText(textViewId, textViewValue);
        Notification notification = new NotificationCompat.Builder(context)
                .setSmallIcon(smallIcon)
                .setAutoCancel(autoCancel)
                .setOngoing(isOnGoing)
                .setContentIntent(resultPendingIntent)
                .setContentTitle(title).build();
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN){
        	notification.bigContentView = expandedView;
        }
        return notification;
    }

}
